package servidor.mundo;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.sql.ResultSet;
import java.util.ArrayList;

import servidor.mundo.basesdedatos.IBD;
import servidor.mundo.entidades.Estadistica;
import servidor.mundo.entidades.Examen;
import servidor.mundo.entidades.Pregunta;

public class ThreadAtenderUsuario extends Thread 
{
	public final static String FIN = "FIN";
	private PrintWriter out;
	private BufferedReader in;
	private Socket socket;
	private IBD bd;
	
	public ThreadAtenderUsuario( Socket canal, IBD base ) throws Exception
	{
		try {
			out = new PrintWriter( canal.getOutputStream( ), true );
			in = new BufferedReader( new InputStreamReader( canal.getInputStream( ) ) );
	        socket = canal;
	        bd = base;
		} catch (IOException e) {
			throw new Exception( "No se pudo obtener el canal del cliente" );
		}
        
	}
	
	public void run( )
	{
		try 
		{
			while( true )
				procesarMensaje( );
		} 
		catch (Exception e) 
		{
			try {
				out.println("KO");
			} catch (Exception ee){
				//Si no puede mandar mensaje de error, no haga nada
			} 
			System.out.println( "COMM ERROR, Desconectando cliente: "+e.getMessage() );
		} 
		finally 
		{
			try {
				in.close();
				out.close();
				socket.close();
			} catch( Exception e ){
				//Ignorar
			}
		}
		
	}
	
	private void procesarMensaje( ) throws Exception
	{
		String linea = in.readLine();
		String[] params = linea.split(":");
		
		if( linea.startsWith( "DESCRIPCION" ) )
			enviarExamen( params[1] );
		else if( linea.startsWith( "REGISTRAR" ) )
			registrarResultados( params[1] );
		else if( linea.startsWith( "REANUDAR" ) )
			reanudarExamen( params[1], Integer.parseInt( params[2] ) );
		else if( linea.startsWith( "CONSULTAR" ) )
			enviarEstadisticas( params[1] );
		else
			out.println("COMANDO INVALIDO");
	}
	
	private void enviarExamen( String examen ) throws Exception
	{
		Examen ex = bd.darExamen( examen );
		out.println( "DESCRIPCION:" + ex.getDescripcion() );
		String linea = in.readLine();
		out.println( "INICIAR:" + ex.getCodigo() + ":" + ex.getPreguntas().size() );
		
		for( int i = 0; i < 20 && i < ex.getPreguntas().size(); i++ )
		{
			Pregunta p = ex.getPreguntas().get(i);
			String preg = "PREGUNTA:" + p.getTipo() + "~" + p.getArea()+ "~" + p.getEnunciado() + "~" + p.getImagen() + "~";
			for( String s : p.getOpciones() )
				preg += s + "~";

			preg += p.getRespuesta() + "~";
			
			out.println( preg );
			
			if( !p.getImagen().equals("") )
				enviarImagen( p.getImagen() );
			
			out.println( "FIN_ARCHIVO" );
		}
		out.println( "OK" );
	}
	
	private void reanudarExamen( String examen, int inicio ) throws Exception
	{
		Examen ex = bd.darExamen( examen );
		
		for( int i = inicio; i < i+20 && i < ex.getPreguntas().size(); i++ )
		{
			Pregunta p = ex.getPreguntas().get(i);
			String preg = "PREGUNTA:" + p.getTipo() + "~" + p.getArea() + "~" + p.getEnunciado() + "~" + p.getImagen() + "~";
			for( String s : p.getOpciones() )
				preg += s + "~";
			
			preg += p.getRespuesta() + "~";
			
			out.println( preg );
			
			if( !p.getImagen().equals("") )
				enviarImagen( p.getImagen() );
			
			out.println( "FIN_ARCHIVO" );
		}
		out.println( "OK" );
	}
	
	private void enviarEstadisticas( String nombre ) throws Exception
	{
		Estadistica e = bd.darEstadisticas( nombre );
		
		int general = e.getGeneral();
		out.println( "GENERAL:" + general );
		
		for( String area : e.getAreas() )
			out.println( "AREA:" + area );
		
		int tiempo = e.getTiempo();
		out.println( "TIEMPO:" + tiempo );
		
		out.println("OK");
	}
	
	private void registrarResultados( String examen ) throws Exception
	{
		Estadistica e = new Estadistica( );
		e.setExamen(examen);
		String linea = in.readLine();
		
		String general = linea.split(":")[1];
		e.setGeneral( Integer.parseInt(general) );
		
		linea = in.readLine();
		while( !linea.startsWith("TIEMPO") )
		{
			e.addArea( linea.split(":")[1] + ":" + linea.split(":")[2] );
			linea = in.readLine();
		}
		
		String tiempo = linea.split(":")[1];
		e.setTiempo( Integer.parseInt(tiempo) );
		
		bd.registrarResultados( e );
		
		out.println("OK");
	}
	
	private void enviarImagen( String imagen ) throws Exception
	{
		FileInputStream flujoEntrada = new FileInputStream( imagen );
		int unByte = flujoEntrada.read();
		while(unByte != -1)
		{
			out.println("BYTE:" + unByte + '\0');
			unByte = flujoEntrada.read();
		}
		flujoEntrada.close();
	}
}
